#pragma once
#include <vector>
#include <glm/glm.hpp>
using namespace glm;
using namespace std;

class ImageBuffer{
public:
	ImageBuffer(int _w, int _h, int _d, int _numLayers = 1);
	ImageBuffer(ImageBuffer* _other);
	~ImageBuffer();

	//set a pixel value
	void pixel(int _x, int _y, int _z, vec4 _col);
	//void pixel(int _x, int _y, vec3 _col);

	//get a pixel value
	vec4 pixel(int _x, int _y, int _z);

	void clear();

	//perform a convolution on _sourceLayer and store it in _destinationLayer
	//void convolve(mat3 _kernel, int _sourceLayer, int _destinationLayer);

	//perform a Sobel edge detection
	//void edgeDetect(int _sourceLayer, int _destinationLayer);

	//convert the image to greyscale
	//0 = average the RGB values
	//1 = pick the highest RGB value
	//void toGrey(int _mode, int _sourceLayer, int _destinationLayer);

	//return a pointer to an array of pixel values
	//float* toFloatArray();

	int width(){ return imgW; }
	int height(){ return imgH; }
	int depth(){ return imgD; }

	void resize(int _width, int _height, int _depth);

	int layers(){ return layerCount; }
	void layers(int _l);	//set the number of layers

	//get a row of pixels
	//vector<vec4> rowAt(int _r);

	//get a vector of all the pixels of the active layer
	vector<vec4> pixels();

	int activeLayer(){ return theActiveLayer; }
	void activeLayer(int _l);

	//get the minimum and maximum values of a particular layer
	//only available for image operations (edge detect and such)
	vec2 minMaxVals(int _l);
	

private:
	vector<vector<vec4>> theImage;
	vector<vec2> theMinMaxVals;

	//do a convolution for a single pixel
	//vec4 convolve(mat3 _kernel, int _sourceLayer, int _x, int _y);
	int pixIndex(int _x, int _y, int _z);	//get the index number for a given pixel
	void updateMinMax(int _layer, float _a);	//if the parameter is higher or lower than the max or min, update the max or min
	void initMinMax();

	//image width and height
	int imgW;
	int imgH;
	int imgD;
	int layerCount;

	int theActiveLayer;
};

